/**
 * API错误处理工具
 */
import { APIError } from '../interfaces/qwen';

/**
 * API错误处理类
 */
export class APIErrorHandler {
    private maxRetries = 3;
    private baseDelay = 1000; // 初始重试延迟(ms)

    /**
     * 使用重试策略执行API请求
     * @param fn 请求函数
     * @param options 重试选项
     * @returns 请求结果
     */
    async executeWithRetry<T>(
        fn: () => Promise<T>,
        options: {
            maxRetries?: number;
            retryableErrors?: number[];
        } = {}
    ): Promise<T> {
        const { maxRetries = this.maxRetries, retryableErrors = [429, 500, 502, 503, 504] } = options;
        let lastError: Error | null = null;

        for (let attempt = 0; attempt <= maxRetries; attempt++) {
            try {
                return await fn();
            } catch (error) {
                lastError = error as Error;

                // 检查是否可重试的错误
                if (
                    attempt < maxRetries &&
                    (
                        (error as any).status && retryableErrors.includes((error as any).status) ||
                        error instanceof TypeError || // 网络错误
                        (error as any).code === 'ECONNRESET'
                    )
                ) {
                    // 指数退避策略
                    const delay = this.calculateRetryDelay(attempt);
                    console.log(`API调用失败，${delay}ms后重试(${attempt + 1}/${maxRetries})`, error);
                    await this.sleep(delay);
                    continue;
                }

                // 不可重试的错误或达到最大重试次数
                break;
            }
        }

        // 重试失败，抛出最后一个错误
        throw lastError;
    }

    /**
     * 计算重试延迟时间
     * @param attempt 尝试次数
     * @returns 延迟时间(ms)
     */
    private calculateRetryDelay(attempt: number): number {
        // 指数退避策略: baseDelay * 2^attempt + random jitter
        return this.baseDelay * Math.pow(2, attempt) + Math.random() * 1000;
    }

    /**
     * 等待指定时间
     * @param ms 毫秒数
     */
    private sleep(ms: number): Promise<void> {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    /**
     * 解析API错误
     * @param error 错误对象
     * @returns 格式化的API错误
     */
    parseAPIError(error: any): APIError {
        // 网络错误
        if (error instanceof TypeError && error.message.includes('fetch')) {
            return {
                code: 'NETWORK_ERROR',
                status: 0,
                message: '网络连接失败，请检查网络设置',
                isRetryable: true
            };
        }

        // API响应错误
        if (error.response) {
            try {
                const data = error.response.data || {};
                const status = error.response.status;

                // 常见错误处理
                switch (status) {
                    case 400:
                        return {
                            code: data.code || 'BAD_REQUEST',
                            status,
                            message: '请求格式不正确，请检查输入',
                            isRetryable: false
                        };
                    case 401:
                        return {
                            code: 'UNAUTHORIZED',
                            status,
                            message: 'API密钥无效或已过期，请更新密钥',
                            isRetryable: false
                        };
                    case 429:
                        return {
                            code: 'RATE_LIMITED',
                            status,
                            message: '请求频率超限，请稍后再试',
                            isRetryable: true
                        };
                    default:
                        return {
                            code: data.code || 'API_ERROR',
                            status,
                            message: data.message || '服务器错误，请稍后再试',
                            isRetryable: status >= 500
                        };
                }
            } catch (e) {
                // 解析错误
                return {
                    code: 'PARSE_ERROR',
                    status: error.response.status || 0,
                    message: '服务响应解析失败',
                    isRetryable: true
                };
            }
        }

        // 默认错误
        return {
            code: 'UNKNOWN_ERROR',
            status: 0,
            message: error.message || '未知错误',
            isRetryable: true
        };
    }
} 